home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
-
- #import "Controller.h"
-
- #import <stdio.h>
- #import <syscall.h>
- #import <pwd.h>
- #import <strings.h>
- #import <sys/types.h>
- #import <netdb.h>
- #import <signal.h>
- #import <defaults.h>
- #import <objc/Storage.h>
- #import <soundkit/Sound.h>
-
-
- @implementation Controller
-
- void killCr(char *c, int len)
- {
- int i;
-
- for(i=0;((i<len) && (c[i]!='\0'));i++)
- if (c[i] == '\n')
- c[i] = '\0';
- return;
- }
-
- int membercmp(MemberRecord *r1, MemberRecord *r2)
- {
- return ((!strncmp(r1->user,r2->user,STRING_LENGTH)) &&
- (!strncmp(r1->username,r2->username,STRING_LENGTH)) &&
- (!strncmp(r1->machine,r2->machine,STRING_LENGTH)));
- }
-
- void copymember(MemberRecord *r1, MemberRecord *r2)
- {
- strncpy(r1->user,r2->user,STRING_LENGTH);
- strncpy(r1->username,r2->username,STRING_LENGTH);
- strncpy(r1->machine,r2->machine,STRING_LENGTH);
- r1->port = r2->port;
- return;
- }
-
- DPSTimedEntryProc networkEntryHandler(DPSTimedEntry num,
- double now,
- char *userData)
- {
- [(id)userData doNetworkTimedEntry:(id)userData];
- return 0;
- }
-
- DPSTimedEntryProc alarmEntryHandler(DPSTimedEntry num,
- double now,
- char *userData)
- {
- [(id)userData doAlarmTimedEntry:(id)userData];
- return 0;
- }
-
- - init
- {
- [super init];
- alertSound = nil;
- numberAlarms = 0;
- netTimedEntry = 0;
- return self;
- }
-
- - addMachineQuit:sender
- {
- [NXApp abortModal];
- return self;
- }
-
- - addMachineOk:sender
- {
- [NXApp stopModal];
- return self;
- }
-
- - fetchSound:sender
- {
- id pan;
- const char * const tps[2] = {"snd",NULL};
- char str[STRING_LENGTH];
-
- pan = [OpenPanel new];
- [pan allowMultipleFiles:NO];
-
- if ([pan runModalForTypes:tps]) {
- if (alertSound)
- [alertSound free];
- strncpy(str,[pan filename],STRING_LENGTH);
- if (str && str[0])
- alertSound = [[Sound alloc] initFromSoundfile:str];
- else
- alertSound = nil;
- [soundFileTextField setStringValue:str];
- [self setDefaults:soundFileTextField];
- }
- return self;
- }
-
- - doAlarmTimedEntry:sender
- {
- if (numberAlarms < (MAXALARMS *2)) {
- numberAlarms++;
- [coverButton setState:(![coverButton state])];
- } else {
- numberAlarms = 0;
- DPSRemoveTimedEntry(alarmTimedEntry);
- [coverButton setState:NO];
- }
- return self;
- }
-
- - handleAlarm
- {
- if ([noisyAlertSwitch state]) {
- if (alertSound)
- [alertSound play:self];
- else
- NXBeep();
- }
- if ([visualAlertSwitch state]) {
- alarmTimedEntry=DPSAddTimedEntry(ALARMENTRYPERIOD,
- (DPSTimedEntryProc)alarmEntryHandler,
- (void *)self,
- 30);
- }
- if ([activateOnAlertSwitch state]) {
- if ([NXApp isHidden])
- [NXApp unhide:self];
- }
- return self;
- }
-
- - doOutput:(char *)msg withSender:(MemberRecord *)owner andBold:(BOOL)bold
- {
- int l;
- id p;
- char str[STRING_LENGTH*3+10];
-
- [self getBrowserString:str fromMember:owner];
- sprintf(str,"%s: ",str);
- p = [logText docView];
- l = [p textLength];
- [p setSel:l :l];
- [p replaceSel:str];
- [p setSel:l :[p textLength]];
- if (bold)
- [p setSelFontStyle:NX_BOLD];
- else
- [p setSelFontStyle:NX_ITALIC];
- l = [p textLength];
- [p setSel:l :l];
- [p replaceSel:msg];
- l = [p textLength];
- [p setSel:l :l];
- [p replaceSel:"\n"];
- l = [p textLength];
- [p setSel:l :l];
- return self;
- }
-
- - input:sender
- {
- id matrix;
- int i,s;
- MemberRecord *temp;
- char str[1024];
-
- i = [sender textLength];
- if (1024 < i)
- i = 1024;
-
- [sender selectAll:self];
- s = [sender getSubstring:str start:0 length:i];
- [sender replaceSel:""];
- str[s] = '\0';
-
- [self doOutput:str withSender:(&me) andBold:YES];
-
- matrix = [memberBrowser matrixInColumn:0];
-
- for(i=0;(i<[matrix cellCount]);i++) {
- if ([[matrix cellAt:i :0] state]) {
- temp = [memberStore elementAt:i];
- [speak setSendPort:temp->port];
- [speak sendMessage:str from:(char *)(&me) length:(sizeof(me))];
- }
- }
- [sender selectText:self];
- return self;
- }
-
- - quit:sender
- {
- int i;
- MemberRecord *temp;
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- [speak setSendPort:temp->port];
- [speak goodByeIAmLeaving:(char *)(&me) length:(sizeof(me))];
- }
- [memberStore free];
- [listen removePort];
- [listen free];
- [speak free];
- [NXApp terminate:self];
- return self;
- }
-
- - (BOOL)gotMemberWithMachine:(const char *)machine
- {
- int i;
- MemberRecord *temp;
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- if (!strncmp(temp->machine,machine,STRING_LENGTH))
- return YES;
- }
- return NO;
- }
-
- - (BOOL)gotMember:(MemberRecord *)mem
- {
- int i;
- MemberRecord *temp;
-
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- if (membercmp(mem,temp))
- return YES;
- }
- return NO;
- }
-
- - changePref:sender
- {
- [self setDefaults:sender];
- return self;
- }
-
- - getDefaults:sender
- {
- const char *c;
-
- c = NXReadDefault([NXApp appName],"ShowLogin");
- [loginSwitch setState:((c == NULL) || (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"ShowReal");
- [realSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"ShowMachine");
- [machineSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"UseConference");
- [useConferenceSwitch setState:((c == NULL) || (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"UseNetwork");
- [useNetworkSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"UseNoiseAlert");
- [noisyAlertSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"UseVisualAlert");
- [visualAlertSwitch setState:((c == NULL) || (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"ActivateOnAlert");
- [activateOnAlertSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))];
- c = NXReadDefault([NXApp appName],"SoundFile");
- [soundFileTextField setStringValue:c];
-
- return self;
- }
-
- - setDefaults:sender
- {
- char str[10];
- char param[20];
- const char *c;
- char strn[64];
-
- // Yes, in case you were wondering, this _is_ Evil, not to mention
- // sloppy in the extreme.
-
- if (sender == loginSwitch)
- strncpy(param,"ShowLogin",20);
- else if (sender == realSwitch)
- strncpy(param,"ShowReal",20);
- else if (sender == machineSwitch)
- strncpy(param,"ShowMachine",20);
- else if (sender == useConferenceSwitch)
- strncpy(param,"UseConference",20);
- else if (sender == useNetworkSwitch)
- strncpy(param,"UseNetwork",20);
- else if (sender == noisyAlertSwitch)
- strncpy(param,"UseNoiseAlert",20);
- else if (sender == visualAlertSwitch)
- strncpy(param,"UseVisualAlert",20);
- else if (sender == activateOnAlertSwitch)
- strncpy(param,"ActivateOnAlert",20);
- else if (sender == soundFileTextField) {
- NXWriteDefault([NXApp appName],"SoundFile",[sender stringValue]);
- if (alertSound)
- [alertSound free];
-
- c = [sender stringValue];
- if (c && c[0]) {
- strncpy(strn,c,64);
- alertSound = [[Sound alloc] initFromSoundfile:str];
- }
- return self;
- }
-
- if ([sender state])
- strncpy(str,"YES",10);
- else
- strncpy(str,"NO",10);
- NXWriteDefault([NXApp appName],param,str);
-
- if ((sender == useConferenceSwitch) && ([sender state]) &&
- (NX_ALERTDEFAULT==NXRunAlertPanel("Hey!","Load .Conference File now?",
- "Ok","Cancel",NULL)))
- [self doConferenceFile:self];
- if ((sender == useNetworkSwitch) && ([sender state]) &&
- (NX_ALERTDEFAULT==NXRunAlertPanel("Hey!","Scan network now?",
- "Ok","Cancel",NULL)))
- [self doNetwork:self];
-
- [memberBrowser reloadColumn:0];
- return self;
- }
-
- - selectAllMembers:sender
- {
- id p;
- int i;
-
- p = [memberBrowser matrixInColumn:0];
-
- for(i=0;(i<[p cellCount]);i++) {
- [p selectCellAt:i :0];
- }
- return self;
- }
-
- - connectTo:(const char *)machine
- {
- int s;
- MemberRecord *temp;
- int i;
- port_t pt;
-
- if ((!machine) || (!machine[0]) || (machine[0] == '\0'))
- return self;
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- if (!strncmp(machine,temp->machine,STRING_LENGTH))
- return self;
- }
-
- s=NXRunAlertPanel("Hey!",
- "Attempt to connect to %s?",
- "Connect","Do Not Connect",NULL,machine);
- if (s == NX_ALERTDEFAULT) {
- pt = NXPortNameLookup(APPNAME,machine);
- if (PORT_NULL!=pt) {
- [speak setSendPort:pt];
- [speak helloIAm:(char *)(&me) length:(sizeof(me))];
- }
- }
- return self;
- }
-
- - disconnectFrom:(const char *)machine
- {
- int s;
- MemberRecord *temp;
- int i;
-
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- if (!strncmp(machine,temp->machine,STRING_LENGTH)) {
- s = NXRunAlertPanel("Hey!",
- "Attempt to disconnect from %s?",
- "Disconnect","Stay Connected",NULL,machine);
- if (s == NX_ALERTDEFAULT) {
- [speak setSendPort:temp->port];
- [speak goodByeIAmLeaving:(char *)&me length:sizeof(me)];
- [memberStore removeAt:i];
- return self;
- }
- }
- }
- return self;
- }
-
- - connectMember:sender
- {
- char c[STRING_LENGTH];
-
- [addMachinePanel makeKeyAndOrderFront:self];
- [addMachineField selectText:self];
-
- if (NX_RUNABORTED == [NXApp runModalFor:addMachinePanel]) {
- [addMachinePanel close];
- return self;
- }
-
- [addMachinePanel close];
- strncpy(c,[addMachineField stringValue],STRING_LENGTH);
- killCr(c,STRING_LENGTH);
- [self connectTo:c];
- [memberBrowser reloadColumn:0];
- return self;
- }
-
- - disconnectMember:sender
- {
- id p;
- int i;
- char c[STRING_LENGTH];
- MemberRecord *temp;
-
- c[0] = '\0';
- p = [memberBrowser matrixInColumn:0];
-
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- if ([[p cellAt:i :0] state]) {
- strncpy(c,temp->machine,STRING_LENGTH);
- killCr(c,STRING_LENGTH);
- }
- }
- if (c[0]) {
- [self disconnectFrom:c];
- }
- [memberBrowser reloadColumn:0];
- return self;
- }
-
- - connectMachine:sender
- {
- id p,q;
- char c[STRING_LENGTH];
-
- p = machineBrowser;
-
- q = [[p matrixInColumn:[p selectedColumn]] selectedCell];
- if (q == nil)
- return self;
- strncpy(c,[q stringValue],STRING_LENGTH);
-
- killCr(c,STRING_LENGTH);
- [self connectTo:c];
- [memberBrowser reloadColumn:0];
- return self;
- }
-
- - disconnectMachine:sender
- {
- id p,q;
- char c[STRING_LENGTH];
-
- p = machineBrowser;
-
- q = [[p matrixInColumn:[p selectedColumn]] selectedCell];
- if (q == nil)
- return self;
- strncpy(c,[q stringValue],STRING_LENGTH);
-
- killCr(c,STRING_LENGTH);
- [self disconnectFrom:c];
- [memberBrowser reloadColumn:0];
- return self;
- }
-
- - addMachineToConferenceFile:(const char *)machine
- {
- FILE *fd;
- char str[STRING_LENGTH+30];
- char lstr[STRING_LENGTH];
- char *cont;
-
- sprintf(str,"%s/%s",homedir,".ConferenceMachines");
- fd = fopen(str,"r");
- if (fd != NULL) {
- for(cont = fgets(lstr,STRING_LENGTH,fd);
- cont;
- cont = fgets(lstr,STRING_LENGTH,fd)) {
- killCr(lstr,STRING_LENGTH);
- if (!strncmp(lstr,machine,STRING_LENGTH)) {
- fclose(fd);
- return self;
- }
- }
- fclose(fd);
- }
- fd = fopen(str,"a");
- if (fd != NULL) {
- fputs(machine,fd);
- fputc('\n',fd);
- fclose(fd);
- } else {
- fd = fopen(str,"w");
- if (fd != NULL) {
- fputs(machine,fd);
- fputc('\n',fd);
- fclose(fd);
- }
- }
- return self;
- }
-
- - removeMachineFromConferenceFile:(const char *)machine
- {
- FILE *fd;
- char str[STRING_LENGTH+30];
- char lstr[STRING_LENGTH];
- int i;
- char *cont;
- char mach[STRING_LENGTH];
- id tempStore;
-
- strncpy(mach,machine,STRING_LENGTH);
- killCr(mach,STRING_LENGTH);
- tempStore = [[Storage alloc] initCount:0
- elementSize:(sizeof(char) * STRING_LENGTH)
- description:MACHINESTORAGEDESCRIPTION];
- sprintf(str,"%s/%s",homedir,".ConferenceMachines");
- fd = fopen(str,"r");
- if (fd != NULL) {
- for(cont = fgets(lstr,STRING_LENGTH,fd);
- cont;
- cont = fgets(lstr,STRING_LENGTH,fd)) {
- killCr(lstr,STRING_LENGTH);
- if (strncmp(lstr,mach,STRING_LENGTH)) {
- [tempStore addElement:lstr];
- }
- }
- fclose(fd);
- }
- fd = fopen(str,"w");
- if (fd == NULL)
- return self;
- for(i=0;(i<[tempStore count]);i++) {
- fputs([tempStore elementAt:i],fd);
- fputc('\n',fd);
- }
- fclose(fd);
- [tempStore free];
- return self;
- }
-
- - addMachine:sender
- {
- char c[STRING_LENGTH];
-
- [addMachinePanel makeKeyAndOrderFront:self];
- [addMachineField selectText:self];
-
- if (NX_RUNABORTED == [NXApp runModalFor:addMachinePanel]) {
- [addMachinePanel close];
- return self;
- }
-
- [addMachinePanel close];
- strncpy(c,[addMachineField stringValue],STRING_LENGTH);
- killCr(c,STRING_LENGTH);
- if (c[0]) {
- [self addMachineToConferenceFile:c];
- [machineBrowser reloadColumn:0];
- if (strncmp(me.machine,c,STRING_LENGTH)) {
- [self connectTo:c];
- [memberBrowser reloadColumn:0];
- }
- }
- return self;
- }
-
- - removeMachine:sender
- {
- id p,q;
- char c[STRING_LENGTH];
-
- p = machineBrowser;
-
- q = [[p matrixInColumn:[p selectedColumn]] selectedCell];
- if (q == nil)
- return self;
- strncpy(c,[q stringValue],STRING_LENGTH);
-
- killCr(c,STRING_LENGTH);
- if (c && c[0]) {
- [self removeMachineFromConferenceFile:c];
- [machineBrowser reloadColumn:0];
- if (strncmp(me.machine,c,STRING_LENGTH))
- [self disconnectFrom:c];
- [memberBrowser reloadColumn:0];
- }
- return self;
- }
-
- - getBrowserString:(char *)str fromMember:(MemberRecord *)mem
- {
- str[0] = '\0';
-
- if ([loginSwitch state]) {
- sprintf(str,"%s",mem->user);
- }
- if ([realSwitch state]) {
- if (str[0])
- sprintf(str,"%s (%s)",str,mem->username);
- else
- sprintf(str,"(%s)",mem->username);
- }
- if ([machineSwitch state]) {
- if (str[0])
- sprintf(str,"%s@%s",str,mem->machine);
- else
- sprintf(str,"%s",mem->machine);
- }
- return self;
- }
-
- - yeahRight:sender
- {
- if (!strcmp([sender title],"Thomas K. Burkholder")) {
- [sender setTitle:"Waddya want, a picture?"];
- } else {
- [sender setTitle:"Thomas K. Burkholder"];
- }
- return self;
- }
-
- - doConferenceFile:sender
- {
- char *cont;
- port_t pt;
- FILE *fd;
- char str[STRING_LENGTH+30];
- sprintf(str,"%s/%s",homedir,".ConferenceMachines");
- fd = fopen(str,"r");
- if (fd == NULL)
- return self;
-
- for(cont = fgets(str,STRING_LENGTH,fd);
- cont;
- cont = fgets(str,STRING_LENGTH,fd)) {
- killCr(str,STRING_LENGTH);
- if ((![self gotMemberWithMachine:str]) &&
- (strncmp("localhost",str,STRING_LENGTH)) &&
- (strncmp("broadcasthost",str,STRING_LENGTH)) &&
- (strncmp(me.machine,str,STRING_LENGTH))) {
- pt = NXPortNameLookup(APPNAME,str);
- if (PORT_NULL!=pt) {
- [speak setSendPort:pt];
- [speak helloIAm:(char *)(&me) length:(sizeof(me))];
- }
- }
- }
- return self;
- }
-
- - doNetworkTimedEntry:sender
- {
- port_t pt;
- struct hostent *he;
-
- he = gethostent();
-
- if (he == NULL) {
- DPSRemoveTimedEntry(netTimedEntry);
- netTimedEntry = 0;
- return self;
- }
-
- if ((![self gotMemberWithMachine:he->h_name]) &&
- (strncmp("localhost",he->h_name,STRING_LENGTH)) &&
- (strncmp("broadcasthost",he->h_name,STRING_LENGTH)) &&
- (strncmp(me.machine,he->h_name,STRING_LENGTH))) {
- pt = NXPortNameLookup(APPNAME,he->h_name);
- if (PORT_NULL!=pt) {
- [speak setSendPort:pt];
- [speak helloIAm:(char *)(&me) length:(sizeof(me))];
- }
- }
- return self;
- }
-
- - doNetwork:sender
- {
- sethostent(1);
- if (!netTimedEntry)
- netTimedEntry = DPSAddTimedEntry(NETWORKENTRYPERIOD,
- (DPSTimedEntryProc)networkEntryHandler,
- (void *)self,
- NX_BASETHRESHOLD);
- return self;
- }
-
- - appDidInit:sender
- {
- struct passwd *pwent;
- char str[64];
- const char *c;
-
- [self getDefaults:sender];
-
- // Initialize sound alert
- c = [soundFileTextField stringValue];
- if (c && c[0]) {
- strncpy(str,c,64);
- alertSound = [[Sound alloc] initFromSoundfile:str];
- }
-
- // Initialize visual alert
- alertWindow = [NXApp appIcon];
- [[alertWindow setContentView:coverButton] free];
-
- pwent = getpwuid(getuid());
-
- strncpy(homedir,pwent->pw_dir,STRING_LENGTH);
- strncpy(me.user,pwent->pw_name,STRING_LENGTH);
- sscanf(pwent->pw_gecos,"%[^,]",me.username);
- gethostname(me.machine,STRING_LENGTH);
- killCr(me.machine,STRING_LENGTH);
-
- memberStore = [[Storage alloc] initCount:0
- elementSize:(sizeof(MemberRecord))
- description:MEMBERSTORAGEDESCRIPTION];
- speak = [[ConferenceSpeaker alloc] init];
- listen = [[ConferenceListener alloc] init];
- [listen setDelegate:self];
- [listen checkInAs:APPNAME];
- [listen addPort];
-
- if ([useConferenceSwitch state])
- [self doConferenceFile:self];
- [machineBrowser reloadColumn:0];
-
- if ([useNetworkSwitch state])
- [self doNetwork:self];
-
- [memberBrowser reloadColumn:0];
-
- [[inputText docView] setDelegate:self];
- [[inputText docView] setCharFilter:(NXCharFilterFunc)NXFieldFilter];
- [[inputText window] makeKeyAndOrderFront:self];
- [[inputText docView] selectAll:sender];
- return self;
- }
-
- -(int)browser:sender fillMatrix:matrix inColumn:(int)column
- {
- id currentCell;
- int i;
-
- if (sender == memberBrowser) {
- MemberRecord *temp;
- char l[STRING_LENGTH*3 + 10];
-
- for(i=0;(i<[memberStore count]);i++) {
- [matrix addRow];
- currentCell = [matrix cellAt:i :column];
- temp = [memberStore elementAt:i];
- [self getBrowserString:l fromMember:temp];
- [currentCell setStringValue:l];
- [currentCell setLeaf:YES];
- [currentCell setLoaded:YES];
- [currentCell setTag:i];
- }
- return i;
- } else { // sender is machineBrowser
- FILE *fd;
- char str[STRING_LENGTH+30];
- char lstr[STRING_LENGTH];
- char *cont;
-
- sprintf(str,"%s/%s",homedir,".ConferenceMachines");
- fd = fopen(str,"r");
- if (fd == NULL)
- return 0;
- for(i = 0,cont = fgets(lstr,STRING_LENGTH,fd);
- cont;
- cont = fgets(lstr,STRING_LENGTH,fd)) {
- if (lstr && lstr[0] && (lstr[0] != '\n')) {
- [matrix addRow];
- currentCell = [matrix cellAt:i:0];
- [currentCell setStringValue:lstr];
- [currentCell setLeaf:YES];
- [currentCell setLoaded:YES];
- [currentCell setTag:i];
- i++;
- }
- }
- fclose(fd);
- return i;
- }
- }
-
- - textDidEnd:sender endChar:(unsigned short)whyEnd
- {
- if (whyEnd != 0)
- [self input:sender];
- return self;
- }
-
- - (int)helloIAm:(char *)fr length:(int)len
- {
- MemberRecord temp,*mr;
-
- mr = (MemberRecord *)fr;
-
- if ([self gotMember:mr])
- return 0;
- copymember(&temp,mr);
- temp.port = NXPortNameLookup(APPNAME,mr->machine);
- [memberStore addElement:&temp];
- [speak setSendPort:temp.port];
- [speak helloIAm:(char *)(&me) length:(sizeof(me))];
- [memberBrowser reloadColumn:0];
- return 0;
- }
-
- - (int)goodByeIAmLeaving:(char *)fr length:(int)len
- {
- int i;
- MemberRecord *temp;
-
- for(i=0;(i<[memberStore count]);i++) {
- temp = [memberStore elementAt:i];
- if (membercmp((MemberRecord *)fr,temp)) {
- [memberStore removeAt:i];
- }
- }
- [memberBrowser reloadColumn:0];
- return 0;
- }
-
- - (int)sendMessage:(char *)msg from:(char *)fr length:(int)len
- {
- id p;
-
- if ([NXApp isHidden]) {
- [self handleAlarm];
- }
- [self doOutput:msg withSender:(MemberRecord *)fr andBold:NO];
- p = [inputText docView];
- [p setSel:[p textLength] :[p textLength]];
- return 0;
- }
-
- @end
-